Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new CLI option -M or --max-diff for limiting mining to low-difficulty periods #199

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

cculianu
Copy link

@cculianu cculianu commented Aug 20, 2020

This PR is in reference to #193 .

I added a CLI option for limiting when the miner actually mines to when difficulty falls below a certain threshold (default: infinite difficulty). If the work unit's difficulty is below a certain threshold, then the miner will sleep for T seconds (T can be specified as well).

The format of the option is: -M N[:T] (the :T part is optional). Where N=mindiff threshold and T is seconds to sleep before trying again (default 10 seconds if unspecified). E.g.:

./minerd -M 123.5 <-- iff difficulty dips below 123.5, we sleep for 10 seconds, wake up, look if a new work unit has arrived, sleep again, etc.

./minerd -M 5:3 <-- iff difficulty dips below 5, we sleep for 3 seconds and try again.

I find this option is very useful for sha256d testnet mining where you want to wait for difficulty to drop to 1.0 (the 20 minute rule on bitcoin or on bitcoin cash or on bitcoin sv) before mining. Often difficulty for cpu mining on testnet is very high and you can only really mine when diff=1.0. Otherwise you are just burning your CPU needlessly.

Sample output. Running with debug logging and -M 1.0:3:

[2020-08-20 19:53:21] thread 0: 2589.8 > max_diff 1.0, sleeping 3 secs
[2020-08-20 19:53:22] < {"params":["5f31ec7100014b31","6c4b9aaa055630c710df6ab6cd54f602856de440b422262b000c70f100000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2c03a968152f43616c696e277320546573744e657420506f6f6c202d20506f7765726564206279204243484e2fffffffff03c2eb0b00000000001976a9140a373caf0ab3c2b46cd05625b8d545c295b93d7a88ac062c9c04000000001976a9148fc9c85983583e959cc13b6898932f3b14eec88488ac0000000000000000166a14","ef8ce88bf501000000000000",[],"20000000","1b194e32","5f3eaa88",false],"id":null,"method":"mining.notify"}
[2020-08-20 19:53:22] DEBUG: job_id='5f31ec7100014b31' extranonce2=0000000000000000 ntime=5f3eaa88
[2020-08-20 19:53:24] thread 2: 0 hashes, 0.00 khash/s
[2020-08-20 19:53:24] thread 2: 2589.8 > max_diff 1.0, sleeping 3 secs

This option allows you to save on power and CPU burn by not mining if
difficulty exceeds some threshold. It is intended for testnet miners
that only want to mine on testnet when difficulty drops to 1.0.
This is the amount of time to sleep (default 10). The argument
is separated by a colon e.g. 10:60 would sleep 60 seconds if difficulty
is > 10.
Our modifications to upstream had weird formatting.  This has been
fixed. The formatting now is more in line with what the upstream maintainer
seems to be doing in the rest of the codebase.
We will prepare a PR now to upstream so I fixed the version in
configure.ac so as to not have it appear in the PR.
@pooler
Copy link
Owner

pooler commented Aug 27, 2020

I'm honestly not sure whether I want to support this functionality in cpuminer, but I do have a question: is there any particular reason why the difficulty is checked against nbits rather than against the target provided by the server?

By the way, it should be noted that the minimum difficulty is not always 1 (for instance, it is lower than 1 for Litecoin).

@cculianu
Copy link
Author

cculianu commented Aug 27, 2020

I'm honestly not sure whether I want to support this functionality in cpuminer

Your call. I'll just maintain my own fork then. I honestly didn't want to have to maintain a fork but I will do so. To me this is an essential feature.

why the difficulty is checked against nbits rather than against the target provided by the server?

No idea. Probably the server's is better? I just went to the source... for lack of familiarity with this code. Feel free to suggest a change.

By the way, it should be noted that the minimum difficulty is not always 1 (for instance, it is lower than 1 for Litecoin).

Oh. I didn't know that. Feel free to fix or suggest a change.

@pooler
Copy link
Owner

pooler commented Aug 27, 2020

For what it's worth, when I said that I'm honestly not sure whether I want to support this functionality, I meant it literally. I'm still pondering over it.

On a different note, I think it should be possible to get rid of the T parameter entirely. I think it would be better to check the difficulty only once whenever new work is received, and then somehow mark the work unit as non-viable if the target is too low. The miner threads would then just wait (possibly earlier in the loop compared to the current patch) until viable work is available. This would also allow the log message to be printed just once rather than for each thread.

@cculianu
Copy link
Author

cculianu commented Aug 27, 2020

On a different note, I think it should be possible to get rid of the T parameter entirely.

Yeah I hate that parameter. I also want to get rid of it. I'll ponder what you said and try and do it properly when the work unit arrives ... as you described and for the reasons you described. The way I have it now is a hack of hacktastic proportions, for sure. The T parameter is 100% superfluous and useless. You are right. I'll ponder how to fix it ... and also return diff < 1.0 from that function I added.. and maybe push changes here if I do it and ping you again.

Thanks for the advice and direction.

@pooler pooler mentioned this pull request Oct 10, 2020
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants